package com.miyake.dsp.osa.lab.wrapper;

import com.miyake.dsp.osa.lab.AutoSetting;
import com.miyake.dsp.osa.lab.AutoSetting.AutoSettingHandler;
import com.miyake.dsp.osa.lab.Calculator;
import com.miyake.dsp.osa.lab.EdgeNotFoundException;
import com.miyake.dsp.osa.lab.LabUiAnnotation;
import com.miyake.dsp.osa.lab.NoiseDetector;
import com.miyake.dsp.otdr.OtdrSettingTable;
import com.miyake.dsp.otdr.OtdrSettingTable.Setting;
@LabUiAnnotation(caption="Auto Setting")
public class AutoSettingWrapper extends Calculator {
	public static final String INPUT_DISTANCE = "In Distance";
	public static final String INPUT_LOSS = "In Loss";
	public static final String OUTPUT_DISTANCE = "Distance Range";
	public static final String OUTPUT_PULSEWIDTH = "Pulse Width";
	public static final String OUTPUT_ATT = "Attenuator";
	public static final String OUTPUT_BANDWIDTH = "Bandwidth";
	public static final String OUTPUT_AVERAGE = "Average Count";
	private AutoSetting setting;
	private double distanceRange;
	private double pulseWidth;
	private OtdrSettingTable table = new OtdrSettingTable();
	private double attenuator;
	private double bandwidth;
	
	public AutoSettingWrapper(final AutoSetting setting) {
		this.setting = setting;
		this.setting.setAutoSettingHandler(new AutoSettingHandler() {

			@Override
			public boolean isReady() {
				if (setting.isInitial()) {
					return true;
				}
				if (//getInput(INPUT_DISTANCE) != null && getInput(INPUT_DISTANCE).getRealPart() != null && 
						getInput(INPUT_LOSS) != null && getInput(INPUT_LOSS).getRealPart() != null) {
					return true;
				}
				else {
					return false;
				}
			}

			@Override
			public void resetReady() {
			}
			
		});
		initInput(INPUT_DISTANCE);
		initInput(INPUT_LOSS);
		initOutput(OUTPUT_DISTANCE);
		initOutput(OUTPUT_PULSEWIDTH);
		initOutput(OUTPUT_ATT);
		initOutput(OUTPUT_BANDWIDTH);
		initOutput(OUTPUT_AVERAGE);
	}

	@Override
	public synchronized void process() {
		if (setting.isStop()) {
			return;
		}
		
		if (setting.getRunMode().equals(AutoSetting.RunMode.Auto)) {
			runAuto();
		}
		else {
			runManual();
		}
	}

	private void runManual() {
		setOutput(OUTPUT_DISTANCE, setting.getDistanceRange());
		setOutput(OUTPUT_PULSEWIDTH, setting.getPulseWidth());
		setOutput(OUTPUT_ATT, 20);
	}

	private void runAuto() {
		double[] inDist;
		double[] inLoss;

		if (!setting.isInitial() && getInput(INPUT_LOSS) != null ) {
			inLoss = getInput(INPUT_LOSS).getRealPart();
			inDist = getInput(INPUT_DISTANCE).getRealPart();
			
			NoiseDetector noiseDetector = new NoiseDetector();
			try {
				noiseDetector.setData(inDist, inLoss);
				double[] noise = noiseDetector.getNoiseStart();
				if (noise.length > 0) {
					distanceRange = table.getRange(noise[0]);
				}
				Setting s = table.getDefaultSetting(distanceRange);
				pulseWidth = s.getPulseWidth();
				attenuator = s.getAttenuator();
				bandwidth = table.getBandwidth(attenuator);
			} catch (EdgeNotFoundException e) {
				setting.setStop(true);
			}

		//	this.setting.setStop(true);
		}
		else {
			setting.setInitial(false);
			distanceRange = 50;
			pulseWidth = 500;
			attenuator = 20;
			bandwidth = 1e6;
		}
		
		setOutput(OUTPUT_DISTANCE, distanceRange);
		setOutput(OUTPUT_PULSEWIDTH, pulseWidth);
		setOutput(OUTPUT_ATT, attenuator);
		setOutput(OUTPUT_BANDWIDTH, bandwidth);
		setOutput(OUTPUT_AVERAGE, 1);
	}

	@Override
	public Object getSetting() {
		return setting;
	}

}
